package sg.edu.nus.iss.billing.gui.component;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class CustomizableJTable extends JTable {
	
	public static final String CHECKBOX_STYLE = "CheckboxStyle";
	public static final String BUTTON_STYLE = "ButtonStyle";
	public static final String NORMAL_STYLE = "NormalStyle";
	private String [] _styles;
	private int [] _columnWidths;
	private List<ColumnAction> columnActions;
	private int rowCount;
	
	public CustomizableJTable(Vector columnNames, int rowCount, String [] styles, int [] columnWidths) throws Exception {
	    this.columnActions = new ArrayList<ColumnAction>();
	    this.rowCount = rowCount;
		this._styles = styles;
		if (columnNames.size() != styles.length) {
			throw new Exception("Column Names and Styling must be same size.");
		}
		if (columnWidths != null && columnWidths.length != columnNames.size()) {
		    throw new Exception("Column Names and Column Widths must be same size.");
		}
		
		TableModel tableModel = 
            new DefaultTableModel(columnNames, rowCount) {
                @Override
                public boolean isCellEditable(int row, int column) {
                	if (CHECKBOX_STYLE.equals(_styles[column]) || BUTTON_STYLE.equals(_styles[column])) {
                		return true;
                	} else {
                		return false;
                	}
                    
                }
        };
        
        this.setModel(tableModel);
        this._columnWidths = columnWidths;
        initCustomizeTableControls();
	}
	
	public void addColumnAction(ColumnAction columnAction) {
	    this.columnActions.add(columnAction);
	}
	
	public CustomizableJTable(Vector columnNames, int rowCount, String [] styles) throws Exception {
	    this(columnNames, rowCount, styles, null);
	}
	
	private void initCustomizeTableControls() {
		for (int i=0; i < this._styles.length; i++) {
		    TableColumn col = this.getColumnModel().getColumn(i);
			if (CHECKBOX_STYLE.equals(_styles[i])) {
				col.setCellRenderer(new CheckBoxRenderer());
				JCheckBox checkBox = new JCheckBox();
			    checkBox.setHorizontalAlignment(JLabel.CENTER);
				col.setCellEditor(new DefaultCellEditor(checkBox));
				if (_columnWidths != null && _columnWidths[i] != 0) {
				    col.setPreferredWidth(_columnWidths[i]);
				}
			} else if (BUTTON_STYLE.equals(_styles[i])) {
				col.setCellRenderer(new ButtonRenderer());
				col.setCellEditor(new ButtonEditor(new JCheckBox()));
                if (_columnWidths != null && _columnWidths[i] != 0) {
                    col.setPreferredWidth(_columnWidths[i]);
                }				
			} else {
                if (_columnWidths != null && _columnWidths[i] != 0) {
                    col.setPreferredWidth(_columnWidths[i]);
                }
			}
		}
	}
	
	public void removeData() {
	    DefaultTableModel model = (DefaultTableModel)this.getModel();
        model.getDataVector().removeAllElements();
	}
	
	public void refreshTable(int rowCount) {
	    removeData();
	    DefaultTableModel model = (DefaultTableModel)this.getModel();
	    model.setRowCount(rowCount);
	}
	
	public void doButtonDownAction(int xcellpos, int ycellpos) {
	    for (int i=0; i < columnActions.size(); i++) {
	        ColumnAction columnAction = columnActions.get(i);
	        Object[]params = new Object[this.rowCount];
	        for (int j=0; j < this.rowCount; j++) {
	            params[j] = this.getValueAt(xcellpos, j);
	        }	        
	        columnAction.actionPerformed(ycellpos, params);
	    }
	}
	
    private class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
        public CheckBoxRenderer() {
            setHorizontalAlignment(JLabel.CENTER);
        }
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                // super.setBackground(table.getSelectionBackground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
            }
            setSelected((value != null && ((Boolean) value).booleanValue()));
            return this;
        }
    }
    
    private class ButtonRenderer extends JButton implements TableCellRenderer {
        public ButtonRenderer() {
            setOpaque(true);
        }
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(UIManager.getColor("Button.background"));
            }
            setText((value == null) ? "" : value.toString());
            return this;
        }
    }
    
    private class ButtonEditor extends DefaultCellEditor {
        protected JButton button;
        private String label;
        private boolean isPushed;
        private int clickX;
        private int clickY;

        public ButtonEditor(JCheckBox checkBox) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    fireEditingStopped();
                }
            });
        }

        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            if (isSelected) {
                button.setForeground(table.getSelectionForeground());
                button.setBackground(table.getSelectionBackground());
            } else {
                button.setForeground(table.getForeground());
                button.setBackground(table.getBackground());
            }
            label = (value == null) ? "" : value.toString();
            button.setText(label);
            isPushed = true;
            clickX = row;
            clickY = column;
            return button;
        }

        public Object getCellEditorValue() {
            if (isPushed) {
            	doButtonDownAction(clickX, clickY);
            }
            isPushed = false;
            return new String(label);
        }

        public boolean stopCellEditing() {
            isPushed = false;
            return super.stopCellEditing();
        }

        protected void fireEditingStopped() {
            super.fireEditingStopped();
        }
    }

}
